﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Zore.App.Shared.Helpers
{
    public static class NumberHelper
    {
        public static decimal RoundTo(this decimal value, int decimalPlaces)
        {
            return Math.Round(value, decimalPlaces);
        }

        public static double RoundTo(this double value, int decimalPlaces)
        {
            return Math.Round(value, decimalPlaces);
        }

        public static decimal RoundToNearest(this decimal value, decimal nearest)
        {
            return Math.Round(value / nearest) * nearest;
        }

        public static double Sqrt(this double value)
        {
            return Math.Sqrt(value);
        }

        public static string ToCurrency(this decimal value, string currencySymbol = "$", int decimalPlaces = 2, bool symbolBeforeValue = true)
        {
            string format = symbolBeforeValue ? $"{currencySymbol}0.{new string('0', decimalPlaces)}" : $"0.{new string('0', decimalPlaces)}{currencySymbol}";
            return value.ToString(format);
        }

        public static string ToCurrency(this decimal value, string cultureInfo = "zh-CN")
        {
            return value.ToString("C", new CultureInfo(cultureInfo));
        }

        public static string ToPercent(this decimal value, int decimalPlaces = 0)
        {
            return value.ToString($"P{decimalPlaces}");
        }

        public static bool IsInRange(this int value, int minValue, int maxValue)
        {
            return value >= minValue && value <= maxValue;
        }

        public static bool IsInRange(this double value, double minValue, double maxValue)
        {
            return value >= minValue && value <= maxValue;
        }

        public static string ToOrdinal(this int value)
        {
            if (value <= 0) return value.ToString();
            switch (value % 100)
            {
                case 11:
                case 12:
                case 13:
                    return $"{value}th";
            }
            switch (value % 10)
            {
                case 1:
                    return $"{value}st";
                case 2:
                    return $"{value}nd";
                case 3:
                    return $"{value}rd";
                default:
                    return $"{value}th";
            }
        }

        public static double PercentageOf(this double value, double total)
        {
            if (total == 0) return 0;
            return (value / total) * 100;
        }

        public static bool IsEven(this int value)
        {
            return value % 2 == 0;
        }

        public static bool IsOdd(this int value)
        {
            return value % 2 != 0;
        }

        public static bool IsPositive(this decimal value)
        {
            return value > 0;
        }

        public static bool IsNegative(this decimal value)
        {
            return value < 0;
        }

        public static bool IsBetween(this int value, int lowerBound, int upperBound)
        {
            return value >= lowerBound && value <= upperBound;
        }

        public static decimal? ToNullableDecimal(this string value)
        {
            if (decimal.TryParse(value, out decimal result))
            {
                return result;
            }
            return null;
        }

        public static int ToInteger(this string value)
        {
            if (int.TryParse(value, out int result))
            {
                return result;
            }
            else
            {
                throw new ArgumentException("Invalid input string. Cannot convert to integer.");
            }
        }
    }
}
